package com.sky.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.User;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkspaceService;
import com.sky.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

/**
 * ClassName: ReportServiceImpl
 * Package: IntelliJ IDEA
 *
 * @author 张文豪
 * @description
 * @date 2023/8/20 15:04
 */
@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private WorkspaceService workspaceService;
    @Override
    public TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> list = fillDate(begin, end);
        //设置与其对应的营业额
        List<BigDecimal> list1 = new ArrayList<>();
        for (LocalDate localDate : list) {
            LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
            LocalDateTime beginTime = LocalDateTime.of(localDate, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(localDate,LocalTime.MAX);
            wrapper.lt(Orders::getOrderTime,endTime).gt(Orders::getOrderTime,beginTime)
                    .eq(Orders::getStatus,Orders.COMPLETED);
            List<Orders> orders = orderMapper.selectList(wrapper);
            if(orders != null && orders.size() > 0){
                BigDecimal subDecimal = BigDecimal.ZERO;
                for (Orders order : orders) {
                    BigDecimal amount = order.getAmount();
                    subDecimal = subDecimal.add(amount);
                }
                list1.add(subDecimal);
            }
        }
       return TurnoverReportVO.builder().dateList(StringUtils.join(list,","))
                .turnoverList(StringUtils.join(list1,","))
                .build();
    }
    private List<LocalDate> fillDate(LocalDate begin, LocalDate end){
        List<LocalDate> list = new ArrayList<>();
        list.add(begin);
        while(!begin.equals(end)){
            begin = begin.plusDays(1);
            list.add(begin);
        }
        return list;
    }

    @Override
    public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {
        //填充日期
        List<LocalDate> list = fillDate(begin, end);
        //当天的用户总数
        List<Integer> totalList = new ArrayList<>();
        //新增的用户数
        List<Integer> changeList = new ArrayList<>();

        //总的用户
        for (LocalDate localDate : list) {
            //查询当天总用户数
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            LocalDateTime endTime = LocalDateTime.of(localDate,LocalTime.MAX);
            wrapper.lambda().lt(User::getCreateTime,endTime);
            Integer todayInteger = userMapper.selectCount(wrapper);

            totalList.add(todayInteger);
            //查询前一天的用户总数
            QueryWrapper<User> beforeWrapper = new QueryWrapper<>();
            LocalDateTime beforeEndTime = LocalDateTime.of(localDate.plusDays(-1),LocalTime.MAX);
            beforeWrapper.lambda().lt(User::getCreateTime,beforeEndTime);
            Integer befortInteger = userMapper.selectCount(beforeWrapper);
            //计算变化的用户数
            Integer changeInteger = todayInteger - befortInteger;
            changeList.add(changeInteger);
        }

        return UserReportVO.builder().newUserList(StringUtils.join(changeList,","))
                .totalUserList(StringUtils.join(totalList,",")).dateList(StringUtils.join(list,",")).build();
    }

    @Override
    public OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> list = fillDate(begin, end);
        //当天有限和总的订单列表
        List<Integer> orderCountList = new ArrayList<>();
        List<Integer> validOrderCountList = new ArrayList<>();
        for (LocalDate date : list) {
            LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date,LocalTime.MAX);
            wrapper.lt(Orders::getOrderTime,endTime).gt(Orders::getOrderTime,beginTime);
            int size = orderMapper.selectList(wrapper).size();
            orderCountList.add(size);

            LambdaQueryWrapper<Orders> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.lt(Orders::getOrderTime,endTime).gt(Orders::getOrderTime,beginTime).eq(Orders::getStatus,Orders.COMPLETED);
            int validSize = orderMapper.selectList(lambdaQueryWrapper).size();
            validOrderCountList.add(validSize);
        }
        //订单总数
        Integer totalOrderCount = new Integer(0);
        for (Integer integer : orderCountList) {
            totalOrderCount+=integer;
        }
        //有效订单数
        Integer validOrderCount = new Integer(0);
        for (Integer integer : validOrderCountList) {
            validOrderCount+=integer;
        }
        //订单完成率
        Double orderCompletionRate = 0.0;
        orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount;
        //填充到vo对象中
        return OrderReportVO.builder().dateList(StringUtils.join(list,","))
                .validOrderCount(validOrderCount).
                validOrderCountList(StringUtils.join(validOrderCountList,","))
                .orderCountList(StringUtils.join(orderCountList,","))
                .totalOrderCount(totalOrderCount).orderCompletionRate(orderCompletionRate)
                .build();
    }
    //TODO 需求太难了，不做了
//    SELECT SUM(od.number) number,od.name
//    FROM order_detail od,orders o
//    WHERE od.order_id = o.id
//    AND o.status = 5
//    GROUP BY od.name
//    ORDER BY number
//    LIMIT 0,10


    @Override
    public SalesTop10ReportVO getTop10(LocalDate begin, LocalDate end) {
        QueryWrapper<OrderDetail> wrapper = new QueryWrapper<>();
        //todo 用mapper查询top10
        return null;
    }


    @Override
    public void exportData(HttpServletResponse response) {
        LocalDate beginDate = LocalDate.now().minusDays(30);
        LocalDate endDate = LocalDate.now().minusDays(1);
        BusinessDataVO businessData = workspaceService.getBusinessData(LocalDateTime.of(beginDate, LocalTime.MIN), LocalDateTime.of(endDate, LocalTime.MAX));
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        try {
            XSSFWorkbook excel = new XSSFWorkbook(in);
            XSSFSheet sheet1 = excel.getSheet("sheet1");
            sheet1.getRow(1).getCell(1).setCellValue("时间：" + beginDate + "至" + endDate);
            XSSFRow row = sheet1.getRow(3);
            row.getCell(2).setCellValue(businessData.getTurnover());
            row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
            row.getCell(6).setCellValue(businessData.getNewUsers());
            XSSFRow row1 = sheet1.getRow(4);
            row1.getCell(2).setCellValue(businessData.getValidOrderCount());
            row1.getCell(4).setCellValue(businessData.getUnitPrice());

            for (int i = 0; i < 30; i++) {
                LocalDate date = beginDate.plusDays(1);
                BusinessDataVO data = workspaceService.getBusinessData(LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));
                row = sheet1.getRow(7 + i);
                row.getCell(1).setCellValue(date.toString());
                row.getCell(2).setCellValue(data.getTurnover());
                row.getCell(3).setCellValue(data.getValidOrderCount());
                row.getCell(4).setCellValue(data.getOrderCompletionRate());
                row.getCell(5).setCellValue(data.getUnitPrice());
                row.getCell(6).setCellValue(data.getNewUsers());
            }
            //获取输出对象
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);
            //
            out.close();
            excel.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
